import { Injectable, Inject, HttpException, HttpStatus } from '@nestjs/common';
import { LoginDto, RegisterDto } from '@/dto/UserLogin.dto';
import UpdateUserInfoDto from '@/dto/UpdateUserInfo.dto';
import { PrismaService } from '@/prisma/prisma.service';
import { RedisService } from '@/redis/redis.service';
import { DEFAULT_AVATAR } from '@/constant';
import { MinioClientService } from '@/minio/MinioClient.service';
import { PaginationService } from '@/hooks/usePagination';

@Injectable()
export class UserService {
  @Inject(PrismaService)
  private prisma: PrismaService;

  @Inject(RedisService)
  private readonly redisService: RedisService;

  @Inject(MinioClientService)
  private readonly minioClientService: MinioClientService;

  @Inject(PaginationService)
  private readonly paginationService: PaginationService;

  async login(userInfo: LoginDto) {
    const { phone, password } = userInfo;
    const user = await this.prisma.user.findFirst({
      where: {
        phone,
        password,
      },
    });
    return user;
  }

  async codeLogin(phone: string) {
    const user = await this.prisma.user.findFirst({
      where: {
        phone,
      },
    });
    return user;
  }

  async validPhone(phone: string) {
    const user = await this.prisma.user.findFirst({
      where: {
        phone,
      },
    });
    return user;
  }

  async register(userInfo: RegisterDto) {
    const { phone, code, password } = userInfo;

    const user = await this.prisma.user.findFirst({
      where: {
        phone,
      },
    });
    if (user) {
      throw new HttpException('用户已存在', HttpStatus.BAD_REQUEST);
    }

    const redisCode = await this.redisService.get(phone);
    if (redisCode !== code) {
      throw new HttpException('验证码错误', HttpStatus.BAD_REQUEST);
    }

    await this.redisService.del(phone);

    const newUser = await this.prisma.user.create({
      data: {
        username: phone,
        phone,
        password,
        avatar: DEFAULT_AVATAR,
      },
    });
    return newUser;
  }

  async collectScenic(userId: number, scenicId: number) {
    const collect = await this.prisma.user_scenic.findFirst({
      where: {
        userId,
        scenicId,
      },
    });
    if (collect) {
      await this.prisma.user_scenic.delete({
        where: {
          id: collect.id,
        },
      });
      return '取消收藏成功';
    }
    try {
      await this.prisma.user_scenic.create({
        data: {
          userId,
          scenicId,
        },
      });
    } catch (e) {
      console.log(e);

      throw new HttpException('收藏失败', HttpStatus.BAD_REQUEST);
    }
    return '收藏成功';
  }

  async starDynamic(userId: number, dynamicId: number) {
    const star = await this.prisma.user_community.findFirst({
      where: {
        userId,
        communityId: dynamicId,
      },
    });
    if (star) {
      await this.prisma.user_community.delete({
        where: {
          id: star.id,
        },
      });
      return '取消点赞成功';
    }
    try {
      await this.prisma.user_community.create({
        data: {
          userId,
          communityId: dynamicId,
        },
      });
    } catch (e) {
      throw new HttpException('点赞失败', HttpStatus.BAD_REQUEST);
    }
    return '点赞成功';
  }

  async getUserInfo(userId: number) {
    const user = await this.prisma.user.findUnique({
      where: {
        id: userId,
      },
      select: {
        id: true,
        avatar: true,
        username: true,
        phone: true,
        area: true,
        hobby: true,
        status: true,
      },
    });
    return user;
  }

  async updateUserInfo(userInfo: UpdateUserInfoDto) {
    const { id, ...rest } = userInfo;

    // 删除原先的用户头像
    const res = await this.prisma.user.findFirst({
      where: {
        id,
      },
      select: {
        avatar: true,
      },
    });
    await this.minioClientService.deleteMinioFile([res.avatar]);
    await this.prisma.user.update({
      where: {
        id,
      },
      data: rest,
    });
    return '更新成功';
  }

  async publishDynamic(userId: number, content: string, img: string[]) {
    await this.prisma.community.create({
      data: {
        userId,
        content,
        community_img: {
          create: img.map((item) => ({
            img: item,
          })),
        },
      },
    });
    return '发布成功';
  }

  async getMyStarDynamic(userId: number, pageNum: number, pageSize: number) {
    const query = {
      where: {
        userId,
      },
      include: {
        community: {
          include: {
            User: {
              select: {
                username: true,
                avatar: true,
              },
            },
            community_img: {
              select: {
                img: true,
              },
            },
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    };

    const res = await this.paginationService.paginate(
      'user_community',
      query,
      pageNum,
      pageSize,
    );
    return res;
  }

  async getMyCollectScenic(userId: number, pageNum: number, pageSize: number) {
    const query = {
      where: {
        userId,
      },
      include: {
        scenic: {
          include: {
            scenic_img: {
              select: {
                img: true,
              },
            },
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    };

    const res = await this.paginationService.paginate(
      'user_scenic',
      query,
      pageNum,
      pageSize,
    );
    return res;
  }

  async getCommentList(communityId: number, pageNum: number, pageSize: number) {
    const query = {
      where: {
        communityId,
      },
      include: {
        User: {
          select: {
            username: true,
            avatar: true,
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    };

    const res = await this.paginationService.paginate(
      'comment',
      query,
      pageNum,
      pageSize,
    );
    return res;
  }

  async postComment(communityId: number, userId: number, content: string) {
    await this.prisma.comment.create({
      data: {
        userId,
        communityId,
        content,
      },
    });
    return '评论成功';
  }

  async deleteDynamic(userId: number, dynamicId: number) {
    const res = await this.prisma.community.findFirst({
      where: {
        id: dynamicId,
      },
      select: {
        userId: true,
        community_img: {
          select: {
            img: true,
          },
        },
      },
    });
    if (!res) {
      throw new HttpException('动态不存在', HttpStatus.BAD_REQUEST);
    }
    if (res.userId !== userId) {
      throw new HttpException('无权限删除', HttpStatus.BAD_REQUEST);
    }

    await this.prisma.$transaction([
      this.prisma.comment.deleteMany({ where: { communityId: dynamicId } }),
      this.prisma.community_img.deleteMany({
        where: { communityId: dynamicId },
      }),
      this.prisma.user_community.deleteMany({
        where: { communityId: dynamicId },
      }),
      this.prisma.community.delete({
        where: { id: dynamicId },
      }),
    ]);

    if (res.community_img.length) {
      await this.minioClientService.deleteMinioFile(
        res.community_img.map((item) => item.img),
      );
    }
    return '删除成功';
  }
}
